/**
 * 路由跳转方法，该方法相对于直接使用uni.xxx的好处是使用更加简单快捷
 * 并且带有路由拦截功能
 */
import queryParams from './queryParams';

/**
 * 路由配置
 */
interface RouterConfig {
    // 跳转类型
    type: string;
    // 跳转地址
    url: string;
    // navigateBack页面后退时,回退的层数
    delta?: number;
    // 传递的参数
    params?: object;
    // 窗口动画,只在APP有效
    animationType?: any;
    // 窗口动画持续时间,单位毫秒,只在APP有效
    animationDuration?: number;
    // 是否需要拦截
    intercept?: boolean;
}

// 请求默认配置
let config: RouterConfig = {
    type: 'navigateTo',
    url: '',
    delta: 1,
    params: {},
    animationType: 'pop-in',
    animationDuration: 300,
    intercept: false,
};

/**
 * 判断url前面是否有"/"，如果没有则加上，否则无法跳转
 * @param url
 * @returns
 */
function addRootPath(url: string): string {
    return url[0] === '/' ? url : `/${url}`;
}

/**
 * 整合路由参数
 * @param url 		路由地址
 * @param params 	传递的对象形式的参数，如{name: 'lisa', age: 18}
 * @returns 		路由地址
 */
function mixinParam(url: string, params: any): string {
    console.log(url);
    url = url && addRootPath(url);

    // 使用正则匹配，主要依据是判断是否有"/","?","="等，如“/page/index/index?name=mary"
    // 如果有url中有get参数，转换后无需带上"?"
    let query = '';
    if (/.*\/.*\?.*=.*/.test(url)) {
        // object对象转为get类型的参数
        query = queryParams(params, false);
        // 因为已有get参数,所以后面拼接的参数需要带上"&"隔开
        return (url += '&' + query);
    } else {
        // 直接拼接参数，因为此处url中没有后面的query参数，也就没有"?/&"之类的符号
        query = queryParams(params);
        return (url += query);
    }
}

/**
 * 执行路由跳转
 * @param config 路由配置
 */
function openPage(config: RouterConfig): void {
    // 解构参数
    const { url, type, delta, animationType, animationDuration } = config;

    if (type == 'navigateTo' || type == 'to') {
        uni.navigateTo({
            url,
            animationType,
            animationDuration,
        });
    }
    if (type == 'redirectTo' || type == 'redirect') {
        uni.redirectTo({
            url,
        });
    }
    if (type == 'switchTab' || type == 'tab') {
        uni.switchTab({
            url,
        });
    }
    if (type == 'reLaunch' || type == 'launch') {
        uni.reLaunch({
            url,
        });
    }
    if (type == 'navigateBack' || type == 'back') {
        uni.navigateBack({
            delta,
            animationType,
            animationDuration,
        });
    }
}

class Router {
    /**
     * 路由跳转
     * @param options 路由地址或者路由参数
     * @param params  传递的对象形式的参数，如{name: 'lisa', age: 18}
     */
    async route(options: any, params?: any) {
        if (typeof options === 'string') {
            // 如果options为字符串，则为route(url, params)的形式
            config.url = mixinParam(options, params);
            config.type = 'navigateTo';
        } else {
            // 否则正常使用config中的url和params进行拼接
            config = { ...config, ...options };
            config.url = mixinParam(options.url, options.params);
        }

        // params参数也带给拦截器
        config.params = params;

        openPage(config);

        // TODO 实现一个拦截器？
        // 判断用户是否定义了拦截器
        //if (typeof uni.$u.routeIntercept === 'function') {
        // 定一个promise，根据用户执行resolve(true)或者resolve(false)来决定是否进行路由跳转
        //	const isNext = await new Promise((resolve, reject) => {
        //		uni.$u.routeIntercept(config, resolve)
        //	})
        // 如果isNext为true，则执行路由跳转
        //	isNext && this.openPage(config)
        //}
    }
}

export default new Router().route;
